/*
 * Date：10/23/18 10:50 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.intellicommunityadmin.controller;

import org.elanfox.intellicommunity.biz.dto.NodeDto;
import org.elanfox.intellicommunity.biz.entity.auth.SystemManager;
import org.elanfox.intellicommunity.biz.service.core.auth.SystemService;
import org.elanfox.intellicommunity.biz.service.core.resident.StructureService;
import org.elanfox.intellicommunity.common.ienum.RoleEnum;
import org.elanfox.intellicommunity.common.utils.LocalDateTimeUtils;
import org.elanfox.intellicommunity.common.utils.RandomUtils;
import org.elanfox.intellicommunity.common.utils.RegexUtils;
import org.elanfox.intellicommunity.intellicommunityadmin.config.SecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.Random;

/**
 * @author guomw
 * @date 2018/9/6
 */
@Controller
public class IndexController {
    @Autowired
    private SystemService systemService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private StructureService structureService;

    @RequestMapping(value = {"login"})
    public String index(HttpServletRequest request, Model model, @AuthenticationPrincipal UserDetails userDetails) {
        if (LocalDateTime.now().isAfter(LocalDateTimeUtils.convert("2021-06-30 23:59:59"))) {
            return "login";
        }
        if (userDetails != null) {
            if (userDetails.isEnabled()) {
                return "redirect:/home";
            }
        }
        String role = RoleEnum.ADMIN.getCode();
        model.addAttribute("role", role);
        return "login";
    }

    @RequestMapping(SecurityConfig.LOGIN_FAILED_URL)
    public String loginFailed(HttpServletRequest request, RedirectAttributes attributes) {
        attributes.addFlashAttribute("errMsg", request.getSession().getAttribute("SPRING_SECURITY_LAST_EXCEPTION"));
        attributes.addFlashAttribute("failedFlag", true);
        return "redirect:login";
    }

    private String getErrorText(Integer code) {
        String text = "403 Forbidden";
        switch (code) {
            case 200:
                text = "success";
                break;
            case 500:
                text = "当前密码不正确";
                break;
            case 0:
                text = "";
                break;
            default:
                break;
        }
        return text;
    }

    @RequestMapping(value = {"/home", "/"})
    public String home(Model model, @AuthenticationPrincipal SystemManager manager, @AuthenticationPrincipal UserDetails userDetails) {
        if (userDetails == null || !userDetails.isEnabled()) {
            return "redirect:/login";
        }
        model.addAttribute("userName", manager.getLoginName());
        return "mainTest";
    }


    @RequestMapping(value = {"/desktop"})
    public String desktop(Model model, @RequestParam(defaultValue = "1") Integer strId, Integer userId) {
        model.addAttribute("strId", strId);
        model.addAttribute("userId", userId);
        return "widgets";
    }

    @RequestMapping(value = {"/map"})
    public String map(Model model, @RequestParam(defaultValue = "1") Integer strId, Integer userId) {
        NodeDto nodeDto = structureService.findNode(strId);
        model.addAttribute("data", nodeDto.getAllUrl());
        model.addAttribute("strId", strId);
        model.addAttribute("strName", nodeDto.getText());
        model.addAttribute("userId", userId);
        return "desktop";
    }

    @RequestMapping("/bank")
    public String bank(@RequestParam(required = false, defaultValue = "403") Integer code,
                       Model model) {
        model.addAttribute("errorCode", code == 0 ? "" : code.toString());
        model.addAttribute("errorText", getErrorText(code));
        return "bank";
    }

    /**
     * 退出注销
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/logout")
    public String logout(HttpServletRequest request) {
        request.getSession().invalidate();
        return "redirect:/login";
    }

    @RequestMapping("/modifypass")
    public String modifyPassword(Model model, @AuthenticationPrincipal SystemManager manager,
                                 HttpServletRequest request,
                                 @AuthenticationPrincipal UserDetails userDetails) {
        model.addAttribute("userName", manager.getLoginName());
        if ("post".equalsIgnoreCase(request.getMethod())) {
            model.addAttribute("failedFlag", true);
            String oldpass = request.getParameter("oldpass");
            String newpass = request.getParameter("newpass");
            if (!passwordEncoder.matches(oldpass, userDetails.getPassword())) {
                model.addAttribute("errMsg", "当前密码错误");
                return "modifypass";
            }

            if (!RegexUtils.checkPassword(newpass, manager.getLoginName())) {
                model.addAttribute("errMsg", "密码必须8-16字符，并且包含字母与数字");
                return "modifypass";
            }


            SystemManager systemManager = systemService.findManagerByLoginName(userDetails.getUsername());
            if (systemManager != null) {
                systemService.modifyManagerPassword(systemManager.getUserId(), passwordEncoder.encode(newpass));
            } else {
                model.addAttribute("errMsg", "用户信息丢失");
                return "modifypasss";
            }
            model.addAttribute("errMsg", "修改成功");
            return "modifypass";
        }
        model.addAttribute("errMsg", "");
        model.addAttribute("failedFlag", false);
        return "modifypass";
    }

    /**
     * 获取图片验证码
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = {"/verifyCode"}, method = RequestMethod.GET)
    public void verifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 创建一张空白的图片
        BufferedImage image = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);
        // 获取该图片的笔画
        Graphics g = image.getGraphics();

        // 绘制背景
        // 设置画笔的颜色
        Random r = new Random();
        g.setColor(new Color(249, 249, 250));
        // 绘制一个实心额矩形区域
        g.fillRect(0, 0, 100, 30);
        // 绘制内容
        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
        g.setFont(new Font(null, Font.BOLD, 25));

        // 生成验证码
        String num = RandomUtils.randomString(5);

        // 验证码的内容保存到session中
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        session.setAttribute("verifyCode", num);
        FontMetrics fontMetrics = g.getFontMetrics();
        int stringWidth = fontMetrics.stringWidth(num);
        int stringAscent = fontMetrics.getAscent();
        int stringDescent = fontMetrics.getDescent();
        //设置内容居中
        g.drawString(num, 100 / 2 - stringWidth / 2, 30 / 2 + (stringAscent - stringDescent) / 2);

        // 将内存中的图片发送到客户端
        response.setContentType("image/jpg");
        OutputStream ops = response.getOutputStream();
        ImageIO.write(image, "jpeg", ops);
    }
}
